package com.github.toyobayashi.nodeexample;

import androidx.appcompat.app.AppCompatActivity;

import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class MainActivity extends AppCompatActivity {
  private Button btn;
  private Button btn2;
  private Button btn3;
  private Button btn4;

  private NodeJs nodejs;
  private boolean copied = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    try {
      nodejs = NodeJs.create();
    } catch (Exception e) {
      Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
      finish();
      return;
    }

    btn = findViewById(R.id.btn);
    btn2 = findViewById(R.id.btn2);
    btn3 = findViewById(R.id.btn3);
    btn4 = findViewById(R.id.btn4);

    btn.setOnClickListener((View v) -> {
      new Thread(() -> {
        try {
         nodejs.evalVoid("Promise.resolve().then(() => throw new Error('micro'))");
        } catch (Exception e) {
          runOnUiThread(() -> {
            Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
          });
          e.printStackTrace();
        }
      }).start();
    });

    btn2.setOnClickListener((View v) -> {
      new Thread(() -> {
        try {
          int r = nodejs.evalInt("2 + 3; 100");
          Log.d("NODE_EXAMPLE", String.valueOf(r));
          r = nodejs.evalInt("2.5 + 0.1");
          Log.d("NODE_EXAMPLE", String.valueOf(r));
          double dv = nodejs.evalDouble("2.5 + 0.1");
          Log.d("NODE_EXAMPLE", String.valueOf(dv));
          boolean b = nodejs.evalBool("process.platform === 'android'");
          Log.d("NODE_EXAMPLE", String.valueOf(b));
          String str = nodejs.evalString("process.version");
          Log.d("NODE_EXAMPLE", str);
          nodejs.evalVoid("notExist");
        } catch (Exception e) {
          runOnUiThread(() -> {
            Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
          });
          e.printStackTrace();
        }
      }).start();
    });

    btn3.setOnClickListener((View v) -> {
      new Thread(() -> {
        try {
          String cache = getCacheDir().getAbsolutePath();
          String jsPath = cache + "/index.js";
          String htmlPath = cache + "/index.html";
          String nodePath = cache + "/addon.node";
          if (!copied) {
            AssetManager am = getAssets();
            copyAssets(am, "index.js", jsPath);
            copyAssets(am, "index.html", htmlPath);
            copyAssets(am, "addon.node", nodePath);
            copied = true;
          }
          int exitCode = NodeJs.runMain(jsPath, new String[]{ "script argument" });
          runOnUiThread(() -> {
            Toast.makeText(MainActivity.this, "Exit: " + exitCode, Toast.LENGTH_SHORT).show();
          });
//          NodeJs nodeInstance = NodeJs.create();
//          nodeInstance.runMain(jsPath);
//          nodeInstance.dispose();
        } catch (Exception e) {
          runOnUiThread(() -> {
            Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
          });
          e.printStackTrace();
        }
      }).start();
    });

    btn4.setOnClickListener((View v) -> {
      try {
        nodejs.evalVoid("process._linkedBinding('android').toast('123')");
      } catch (Exception e) {
        Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
        e.printStackTrace();
      }
    });
  }

  private static void copyAssets (AssetManager am, String src, String dest) {
    try {
      copyAssetFile(am, src, dest);
    } catch (Exception e) {
      try {
        File dir = new File(dest);
        dir.mkdir();
      } catch (Exception e1) {}
      try {
        String[] files = am.list(src);
        for (int i = 0; i < files.length; i++) {
          copyAssets(am, src + "/" + files[i], dest + "/" + files[i]);
        }
      } catch (Exception e2) {}
    }
  }

  private static void copyAssetFile(AssetManager am, String src, String dest) throws IOException {
    InputStream in = am.open(src);

    File destFile = new File(dest);
    if (!destFile.exists()) destFile.createNewFile();

    FileOutputStream out = new FileOutputStream(dest);

    byte[] buffer = new byte[1024];
    int length;
    while ((length = in.read(buffer)) > 0) {
      out.write(buffer, 0, length);
    }
    in.close();
    out.close();
  }
}
